﻿using MongoService.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Driver;
using System.Configuration;
using MongoService.Common;
using Model;
using MongoService.Model;
using System.Collections;

namespace MongoService.Implement
{
    public class MongoRepository<T, TKey> : IMongoRepository<T, TKey> where T : IMongoEntity<TKey>
    {
        public IMongoCollection<T> Collection
        {
            get;
            private set;
        }

        #region 构造函数

        public MongoRepository()
        {
            Collection = MongoDBHelper<TKey>.GetCollection<T>(null);
        }

        public MongoRepository(MongoUrl url)
        {
            Collection = MongoDBHelper<TKey>.GetCollection<T>(url);
        }

        public MongoRepository(string connectionString, string databaseName)
        {
            Collection = MongoDBHelper<TKey>.GetCollection<T>(connectionString, databaseName);
        }

        #endregion

        #region 查询

        /// <summary>
        /// 单条数据查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetById(TKey id)
        {
            return Collection.AsQueryable().FirstOrDefault(t => t.Id.Equals(id));
        }

        /// <summary>
        /// 集合查询
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public IEnumerable<T> GetByFilter(System.Linq.Expressions.Expression<Func<T, bool>> filter)
        {
            return Collection.AsQueryable().Where(filter);
        }

        #endregion

        #region 增加

        /// <summary>
        /// 单条数据添加
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public T Add(T entity)
        {
            Collection.InsertOne(entity);
            return entity;
        }

        /// <summary>
        /// 多条数据添加
        /// </summary>
        /// <param name="entities"></param>
        public void Add(IEnumerable<T> entities)
        {
            Collection.InsertMany(entities);
        }

        #endregion

        #region 更新

        /// <summary>
        /// 单条数据按条件更新全部字段
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Update(System.Linq.Expressions.Expression<Func<T, bool>> filter, T entity)
        {
            var result = Collection.ReplaceOne(filter, entity);
            return result.MatchedCount > 0 && result.ModifiedCount >= 0;
        }

        /// <summary>
        /// 单条数据按条件更新部分字段
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Update(System.Linq.Expressions.Expression<Func<T, bool>> filter, UpdateDefinition<T> entity)
        {
            var result = Collection.UpdateOne(filter, entity);
            return result.MatchedCount > 0 && result.ModifiedCount >= 0;
        }

        /// <summary>
        /// 单条数据按主键ID更新全部字段
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Update(T entity)
        {
            return Update(t => t.Id.Equals(entity.Id), entity);
        }

        /// <summary>
        /// 多条数据按主键ID更新全部字段
        /// </summary>
        /// <param name="entities"></param>
        public void Update(IEnumerable<T> entities)
        {
            foreach (var entity in entities)
            {
                Update(t => t.Id.Equals(entity.Id), entity);
            }
        }

        #endregion

        #region 删除

        /// <summary>
        /// 按主键ID删除单条数据
        /// </summary>
        /// <param name="id"></param>
        public void Delete(TKey id)
        {
            Collection.DeleteOne(Builders<T>.Filter.Eq("_id", id));
        }

        /// <summary>
        /// 按条件删除多条数据
        /// </summary>
        /// <param name="filter"></param>
        public void Delete(System.Linq.Expressions.Expression<Func<T, bool>> filter)
        {
            Collection.DeleteMany(filter);
        }

        #endregion

        #region 集合对象操作

        public IEnumerator<T> GetEnumerator()
        {
            return Collection.AsQueryable<T>().GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public Type ElementType
        {
            get { return Collection.AsQueryable<T>().ElementType; }
        }

        public System.Linq.Expressions.Expression Expression
        {
            get { return Collection.AsQueryable<T>().Expression; }
        }

        public IQueryProvider Provider
        {
            get { return Collection.AsQueryable<T>().Provider; }
        }
        #endregion
    }
}
